package com.hontech.bv.conn

import com.hontech.bv.conn.serial.ByteView
import com.hontech.bv.conn.serial.Uint16
import com.hontech.bv.conn.serial.Uint32
import com.hontech.bv.utils.log
import kotlinx.coroutines.delay
import java.io.IOException
import java.security.MessageDigest
import kotlin.random.Random

object Device {

    private const val OTA_PKG_MAX_SIZE = 96

    suspend fun ota(dest: Int, data: ByteArray, cb: (Int) -> Unit) {

        SerialPortMod.request(
            Proto.REQ_OTA_START,
            dest,
            arrayOf(Uint32(data.size))
        ).assert("OTA Start")

        var index = 0
        var id = 0
        while (index < data.size) {
            var n = data.size - index
            if (n > OTA_PKG_MAX_SIZE) {
                n = OTA_PKG_MAX_SIZE
            }
            SerialPortMod.request(
                Proto.REQ_OTA_TRANSLATE,
                dest,
                arrayOf(Uint16(id), ByteView(data, index, n))
            ).assert("OTA Translate $id")
            index += n
            id ++
            cb(index * 100 / data.size)
        }

        val md5 = MessageDigest.getInstance("MD5")
        val m5 = md5.digest(data)

        SerialPortMod.request(
            Proto.REQ_OTA_COMPLETE,
            dest,
            arrayOf(ByteView(m5, 0, m5.size))
        ).assert("OTA Complete")
    }

    suspend fun ping(dest: Int) {
        val req = ByteView(Random.nextBytes(48))

        val frame = SerialPortMod.request(
            Proto.REQ_PING,
            dest,
            arrayOf(req)
        )
        val ret = ByteView()
        frame.parse(arrayOf(ret))

        if (ret != req) {
            log("ret: ${ret.toHex()}")
            log("req: ${req.toHex()}")
            throw IOException("${frame.info()} 异常 ${ret.size()} ${req.size()}")
        }
    }

}

